import { EventData } from "./EventData";
import ArrayEx from "../Utils/ArrayEx";

export class EventCenter {

    private static _instance: EventCenter;
    public static get instance(): EventCenter {
        return this._instance;
    }

    static CreateInstance(): EventCenter {
        if (this._instance != null) {
            console.log("无法重复初始化EventCenter");
            return this._instance;
        }
        this._instance = new EventCenter();
        return this._instance;
    }

    private _eventMap: Map<string, EventData[]>;

    constructor() {
        this._eventMap = new Map<string, EventData[]>();
    }

    public Regist(eventId: string, caller: any, func: Function, params?: any[], remainCount: number = -1) {
        if (this._eventMap.has(eventId)) {
            let getArray = this._eventMap.get(eventId);

            for (let data of getArray) {
                if (data.IsSame(caller, func)) {
                    data.params = params;
                    data.remainCount = remainCount;
                    return;
                }
            }

            let newData = new EventData();
            newData.caller = caller;
            newData.func = func;
            newData.params = params;
            newData.remainCount = remainCount;

            getArray.push(newData);
        } else {
            let newArray: EventData[] = [];

            let newData = new EventData();
            newData.caller = caller;
            newData.func = func;
            newData.params = params;
            newData.remainCount = remainCount;

            newArray.push(newData);
            this._eventMap.set(eventId, newArray);
        }
    }

    public UnRegist(eventId: string, caller: any, func: Function) {
        if (this._eventMap.has(eventId)) {
            let getArray = this._eventMap.get(eventId);
            for (let i = 0; i < getArray.length; ++i) {
                let data = getArray[i];
                if (data.IsSame(caller, func)) {
                    ArrayEx.RemoveAt(getArray, i);
                    break;
                }
            }
            if (getArray.length == 0) {
                this._eventMap.delete(eventId);
            }
        }
    }

    public Send(eventId: string, params: any[]) {
        if (this._eventMap.has(eventId)) {
            let getArray = this._eventMap.get(eventId);

            for (let i = 0; i < getArray.length; ++i) {
                let data = getArray[i];
                let needDestory = data.Emit(params);
                if (needDestory) {
                    ArrayEx.RemoveAt(getArray, i--);
                }
            }

            if (getArray.length == 0) {
                this._eventMap.delete(eventId);
            }
        }
    }

}